class Numeric
  def minutes
    self * 60
  end

  def hours
    self * 3600
  end
end

module Cacheable
  def self.included(klass)
    def klass.caches(mthd, options)
      self.module_eval <<-END
        alias_method :cacheable_#{mthd}, :#{mthd}

        def #{mthd}
          (@cacheable_caches ||= {})["#{mthd}"] ||= { :ttl => #{options[:for]}, :cached_at => Time.local(0) }
          cacheable_fetch("#{mthd}")
        end
      END
    end
  end

  def cacheable_fetch(method)
    if cacheable_expired?(method)
      cacheable_cache(method)
    end

    cacheable_value(method)
  end

  def cacheable_cache(method)
    value = self.send("cacheable_#{method}".to_sym)
    @cacheable_caches[method][:value] = value
    @cacheable_caches[method][:cached_at] = Time.now
    value
  end

  def cacheable_expired?(method)
    @cacheable_caches[method][:ttl] < (Time.now - @cacheable_caches[method][:cached_at])
  end

  def cacheable_value(method)
    @cacheable_caches[method][:value]
  end

  def cacheable_init(method)
  end
end
